package com.wksc.framework.impexp.handler.exp;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

import com.wksc.framework.impexp.constants.IEConstants;
import com.wksc.framework.impexp.constants.PostfixType;
import com.wksc.framework.impexp.log.ImpExpLog;
import com.wksc.framework.impexp.template.ExpTemplate;
import com.wksc.framework.impexp.util.ClassFactory;
import com.wksc.framework.impexp.writer.XlsWriter;
import jxl.read.biff.BiffException;
import jxl.write.WriteException;

/**
 * <p> Title(文件名): ExpXlsHandler.java </p>
 * <p> Description(描述): 控制Excel文件生成的Handler </p>
 * <p> Copyright(版权): Copyright (c) 2011 </p>
 * <p> Company(公司): 成都四方信息技术有限公司 </p>
 * <p> CreateTime(生成日期)：2011-11-23 下午08:15:23 </p>
 * @author wanglei
 * @version impExp
 */
public class ExpXlsHandler extends BaseExpHandler {
	private static final long serialVersionUID = -5510481680805760155L;

	private static final ImpExpLog log = ClassFactory.getLog(ExpXlsHandler.class);
	private boolean isStatistic;
	
	public ExpXlsHandler(ExpTemplate expTemplate) throws BiffException, FileNotFoundException, IOException {
		super(expTemplate);
	}

	@Override
	public int writeToFile(List<?> data) throws IOException, WriteException,
			BiffException {
		int succNum = 0;
		if (isStatistic) {
			succNum = gridWrite(data);
		} else {
			succNum = normalWrite(data);
		}
		return succNum;
	}
	
	@Override
	protected void init() throws BiffException, FileNotFoundException,
			IOException {
		if(null != expTemplate.getExcelConflate()){
			writer = ClassFactory.getGridViewWrite(expTemplate.getExcelConflate()); //反射取得gridwriter
			isStatistic = true;
		}else{
			writer = new XlsWriter();
		}
	}


	/**
	 * 方法描述：无合并单元格的excel文件写入方法
	 *
	 * @creator wanglei
	 * @param data
	 * @return
	 * @throws WriteException
	 * @throws java.io.IOException
	 * @throws BiffException 
	 */
	private int normalWrite(List<?> data) throws WriteException, IOException, BiffException {
		try {
			writer.initWriter(createFile(), true);
			writeHeadLine();
			return writer.writeByRows(data, expTemplate.getDataRow(),
					expTemplate.getWriteOrder());
		} finally {
			try {
				writer.close();	
			} catch (Exception e) {
				log.error("Close writer error", e);
			}
		}
	}

	/**
	 * 方法描述：有合并单元格的excel文件写入方法
	 *
	 * @creator wanglei
	 * @param data
	 * @return
	 * @throws java.io.IOException
	 * @throws java.io.FileNotFoundException
	 * @throws BiffException 
	 * @throws WriteException 
	 */
	private int gridWrite(List<?> data) throws BiffException,
			FileNotFoundException, IOException, WriteException {
		int succNum = 0;
		// 处理次数
		int processTime = getProcessTime(data);
		// 实际待写入文件的数据
		List<?> dataPerLoop;
		// 划分单次待写入文件的起始行号
		int offset;
		// 划分单次待写入文件的结束行号
		int toIndex;

		for (int i = 0; i < processTime; i++) {
			offset = i * IEConstants.MAX_EXCEL_LINE;
			if (i != processTime - 1) {
				toIndex = (i + 1) * IEConstants.MAX_EXCEL_LINE;
			} else {
				toIndex = data.size();
			}
			// 拆分数据
			dataPerLoop = data.subList(offset, toIndex);
			// 创建文件
			writer.initWriter(createFile(), true);
			try {
				// 写标题行
				writeHeadLine();
				// 写内容
				succNum += writer.writeByRows(dataPerLoop, expTemplate != null ? expTemplate.getDataRow():1  );
			} finally {
				writer.close();
			}
		}
		return succNum;
	}
	
	/**
	 * 方法描述：写标题行
	 *
	 * @creator wanglei
	 * @return
	 * @throws WriteException
	 * @throws java.io.IOException
	 */
	private boolean writeHeadLine() throws WriteException, IOException{
		return writer.writeByRow(expTemplate.getShowedHeader(), 0);
	}
	
    /**
     * 获取单批数据分几次处理
     */
    private int getProcessTime(List<?> data){
    	int processTime = 1;
    	if(IEConstants.MAX_EXCEL_LINE < data.size()){
    		processTime = data.size() / IEConstants.MAX_EXCEL_LINE + 1;
        }
		return processTime;
    }

	@Override
	public PostfixType getPostfix() {
		return PostfixType.XLS;
	}
}
